package mpbe.estructura.secciones.hormigon_armado.graficos;

/*
 * Este codigo es software libre y se encuentra licenciado 
 * bajo los términos de la Licencia Pública General de GNU versión 3 
 * según se encuentra publicada por la Free Software Foundation.
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Autor: Martin Pablo Bellanca <martin.bellanca@gmail.com>
 * web: http://mpbe.blogspot.com/
 */

import java.util.Vector;

import mpbe.estructura.secciones.hormigon_armado.Barra_Redonda;
import mpbe.estructura.secciones.hormigon_armado.EsfuerzosUltimos;
import mpbe.estructura.secciones.hormigon_armado.Hormigon_armado;
import mpbe.estructura.secciones.hormigon_armado.RectaUltima;
import mpbe.estructura.secciones.hormigon_armado.SHFlexion;
import mpbe.estructura.secciones.hormigon_armado.SHGrupo_de_Barras;
import mpbe.estructura.secciones.hormigon_armado.contornos.SHContorno;
import mpbe.geometria.Limites;
import mpbe.geometria.Punto;
import mpbe.MPBE;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Drawable;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Path;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.Transform;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.graphics.Image;


import sun.awt.HorizBagLayout;

/**
 * @author  mpbe
 */
public class SHDibujar {
	//Dibuja la seccion en cualquier objeto dibujable de SWT usando GC
	
	private boolean dibSectorSeccion;
	private boolean dibSectorTension;
	private boolean dibSectorDeformacion;	
		
	// clases de dibujo
	private Rectangle area = null;
//	private Drawable img = null;
	private GC gc = null;
	private Display display = null;	
	
	// Sectores del dibujo
	public SHDibSeccion dib_Seccion = null;
	public SHDibTensiones dib_Tensiones = null;
	public SHDibDeformaciones dib_Deformaciones = null;
	
	//Seccion
	private Hormigon_armado seccion = null;
	private Limites limitesVSeccion= null;
	private Limites limitesHSeccion = null; 
	
	private double escalaX = 1; //escala del dibujo
	private double escalaY = -1; //escala del dibujo
	private int corrimientoX; //distancia ejes globales a ejes locales de la seccion 
	private int corrimientoY;   
	
	private int cantMarcos; //indica cuantas divisiones horizontales tiene el area de dibujo

	// varias
	private double decRedondeo;
	
	//Seccion a dibujar
	public SHDibujar (Display display){
	this.display = display;
		
	dib_Seccion = new SHDibSeccion(display);
	dib_Deformaciones = new SHDibDeformaciones(display);
	dib_Tensiones = new SHDibTensiones(display);
		
	cantMarcos = 1;
	dibSectorSeccion = true;	
	dibSectorTension = false;
	dibSectorDeformacion = false;

	}
	
	public SHDibujar (Display display, GC gc){
		this.display = display;
//		this.img = img;
		this.gc = gc;
		
		dib_Seccion = new SHDibSeccion(display, gc);
		dib_Deformaciones = new SHDibDeformaciones(display, gc);
		dib_Tensiones = new SHDibTensiones(display, gc);
		
		cantMarcos = 1;
		dibSectorSeccion = true;		
		dibSectorTension = false;
		dibSectorDeformacion = false;

	}
	
	//------------------------------------------------------------
	// Funciones de Dibujo Generales
	//------------------------------------------------------------	
	public boolean dibujar (GC gc, Rectangle area){
		boolean res = true;
		setGC(gc);
		
		if (seccion != null) 
			dibujar (seccion, area);	
		else res = false;
		return res;
	}
	public boolean dibujar (Hormigon_armado seccion, Rectangle area){
		this.seccion = seccion;
		this.area = area;
//		img = drawable;
//		this.gc = gc;
		double ulong = seccion.getGenerales().uLongitud.Coef;
		decRedondeo = ulong * 100;
		
		//Obtener las medidas de la seccion
		limitesHSeccion = seccion.contornos.getLimitesH();
		limitesHSeccion.agrandar(15*ulong); //TODO CAMBIAR A PORCENTAJE DEL ANCHO DE LA SECCION O VALOR FIJO DE PIXELS
		limitesVSeccion = seccion.contornos.getLimitesV();
		limitesVSeccion.agrandar(15*ulong); //TODO CAMBIAR A PORCENTAJE DEL ALTO DE LA SECCION O VALOR FIJO DE PIXELS
		
		Rectangle areaSec = new Rectangle((int)limitesHSeccion.min, (int)limitesVSeccion.min, (int)(limitesHSeccion.getLongitud()*cantMarcos), (int)limitesVSeccion.getLongitud());
		
		//Calcular la escala y corrimiento de eje y del dibujo
		escalaX = Escalar(area, areaSec);
		escalaY = -escalaX;
		int YY = corrimiento(area.height, limitesVSeccion, escalaY);
		this.corrimientoY = YY;
		
		//Calcula el rectangulo del dibujo
		int canSec = 0;
		if (this.dibSectorSeccion) canSec++;
		if (this.dibSectorDeformacion) canSec++;
		if (this.dibSectorTension) canSec++;
		if (canSec <= 0) return false; 
		int aa = area.width/canSec;
		int cc = 0;
		
//		gc = new GC(img);
		//Dibuja_seccion con el area asignada
		if (this.dibSectorSeccion) {
			Rectangle areaSeccion = new Rectangle(0, 0, aa-1, area.height-1); 
			cc++;
			corrimientoX = corrimiento(areaSeccion.width, limitesHSeccion, escalaX);
			boolean dibSeccion = dib_Seccion.dibujar_Seccion(escalaX, escalaY, corrimientoX, corrimientoY, areaSeccion); 
		}
		if (this.dibSectorDeformacion) {
			Rectangle areaDeformacion = new Rectangle(aa*cc, 0, aa-1, area.height-1);
			cc++;
			boolean dibDeformacion = dib_Deformaciones.dibujar_Deformacion (escalaX, escalaY, corrimientoX, YY, areaDeformacion);
		}
		if (this.dibSectorTension) {
			Rectangle areaTension = new Rectangle(aa*cc, 0, aa-1, area.height-1);
			boolean dibTension = dib_Tensiones.dibujar_Tension (escalaX, escalaY, corrimientoX, YY, areaTension);
		}
		
		return false;
	}
	
	public static void dibEjeNeutro(GC gc, int corrimientoX, int corrimientoY, double escalaY, Rectangle area, Color color, Hormigon_armado seccion){	
		int dx = area.x;
		int dy = area.y;	
		// puntos de referencia
		int Xbi = dx+5;
		int Xbd = dx+area.width-5;	
		Limites lv = seccion.contornos.getLimitesV();
		double px = lv.max-seccion.getResultados().recta_ultima.X;
		int YY = dy+transformar(px, corrimientoY, escalaY);

		gc.setForeground(color);  //display.getSystemColor(colorEjeNeutro)
		gc.setLineWidth(1);
		gc.setLineStyle(SWT.LINE_DOT);
		
		// dibuja Ejes X

		gc.drawLine(Xbi, YY, Xbd, YY);
		//gc.drawText("X", (int)(imgAncho-13), YaGobal(0)-20);
	}
	
	public static double Escalar(Rectangle areaImg, Rectangle areaSec) {	
		double relg = (double)areaImg.width/(double)areaImg.height;
		double relS = (double)areaSec.width/(double)areaSec.height;
		if (relg>relS)
			// el alto permanece constante
			return (double)areaImg.height/(double)areaSec.height;
		else
			// el ancho permanece constante
			return (double)areaImg.width/(double)areaSec.width;
	}
	//corrimiento del eje local X respecto al global del area de dibujo
	public static int corrimiento(int long1, Limites limites, double escala) {	
		int long2 = (int)(limites.getLongitud()*Math.abs(escala));	
		int bordeSec;
		if (escala>0) bordeSec = (int)(limites.min*escala); else  bordeSec = (int)(limites.max*escala);
		return (long1/2-long2/2+Math.abs(bordeSec));
	}
	
	// Si el eje global tiene distinta direccion que el local la escala debe ser negativa
	public static int transformar(double valor, int corrimiento, double escala){
		return (int) (corrimiento+valor*escala);
	}	
	
	
	//-----------------------------------------
	// Getter y setter de variables boolean Sectores
	//-----------------------------------------
	public void setDibAllSector(boolean bool) {
		dibSectorSeccion = bool;
		dibSectorTension = bool;
		dibSectorDeformacion = bool;
		cantMarcos = 3;
	}
	public void setDibOnlySectorSeccion() {
		dibSectorSeccion = true;
		dibSectorTension = false;
		dibSectorDeformacion = false;
		cantMarcos = 1;
	}
		
 	public boolean isDibSectorSeccion() {
		return dibSectorSeccion;
	}
	public void setDibSectorSeccion(boolean dibSectorSeccion) {
		if (this.dibSectorSeccion != dibSectorSeccion) {
			this.dibSectorSeccion = dibSectorSeccion;
			if (dibSectorSeccion) ++cantMarcos; else --cantMarcos; 
		}
	}

	public boolean isDibSectorTension() {
		return dibSectorTension;
	}
	public void setDibSectorTension(boolean dibSectorTension) {
		if (this.dibSectorTension != dibSectorTension) {
			this.dibSectorTension = dibSectorTension;
			if (dibSectorTension) ++cantMarcos; else --cantMarcos;
		}
	}

	public boolean isDibSectorDeformacion() {
		return dibSectorDeformacion;
	}
	public void setDibSectorDeformacion(boolean dibSectorDeformacion) {
		if (this.dibSectorDeformacion != dibSectorDeformacion) {
			this.dibSectorDeformacion = dibSectorDeformacion;
			if (dibSectorDeformacion) ++cantMarcos; else --cantMarcos;
		}
	}

	
	//-----------------------------------------
	// Getter y setter de Seccion
	//-----------------------------------------	
	/**
	 * @return
	 * @uml.property  name="seccion"
	 */
	public Hormigon_armado getSeccion() {
		return seccion;
	}
	/**
	 * @param seccion
	 * @uml.property  name="seccion"
	 */
	public void setSeccion(Hormigon_armado seccion) {
		this.seccion = seccion;
		dib_Seccion.setSeccion(seccion);
		dib_Tensiones.setSeccion(seccion);
		dib_Deformaciones.setSeccion(seccion);
	}

	
	/**
	 * @return the escala
	 */
	public double getEscala() {
		return escalaX;
	}

	/**
	 * @param escala the escala to set
	 */
	public void setEscala(double escala) {
		this.escalaX = escala;
	}

	/**
	 * @return the corrimientoX
	 */
	public int getCorrimientoX() {
		return corrimientoX;
	}

	/**
	 * @param corrimientoX the corrimientoX to set
	 */
	public void setCorrimientoX(int corrimientoX) {
		this.corrimientoX = corrimientoX;
	}

	/**
	 * @return the corrimientoY
	 */
	public int getCorrimientoY() {
		return corrimientoY;
	}

	/**
	 * @param corrimientoY the corrimientoY to set
	 */
	public void setCorrimientoY(int corrimientoY) {
		this.corrimientoY = corrimientoY;
	}

	
//	public Drawable getDrawable() {
//		return img;
//	}
//
//	public void setDrawable(Drawable img) {
//		this.img = img;
//		dib_Seccion.setDrawable(img);
//		
//		dib_Deformaciones.setDrawable(img);
//		dib_Tensiones.setDrawable(img);
//	}

	public GC getGC() {return gc;}
	public void setGC(GC gc) {
		this.gc = gc;
		dib_Seccion.setGC(gc);
		dib_Deformaciones.setGC(gc);
		dib_Tensiones.setGC(gc);
	}
	
}
